
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file was initially generated by gen_to_start.go (add link), as a start
// of the Traffic Ops golang data model

package api

import (
	"encoding/json"
	_ "github.com/apache/trafficcontrol/traffic_ops/experimental/server/output_format" // needed for swagger
	"github.com/jmoiron/sqlx"
	null "gopkg.in/guregu/null.v3"
	"log"
	"time"
)

type Users struct {
	Username      string      `db:"username" json:"username"`
	Email         null.String `db:"email" json:"email"`
	FullName      null.String `db:"full_name" json:"fullName"`
	SshPubKey     null.String `db:"ssh_pub_key" json:"sshPubKey"`
	LocalPassword null.String `db:"local_password" json:"localPassword"`
	CreatedAt     time.Time   `db:"created_at" json:"createdAt"`
	Links         UsersLinks  `json:"_links" db:-`
}

type UsersLinks struct {
	Self      string    `db:"self" json:"_self"`
	RolesLink RolesLink `json:"roles" db:-`
}

// @Title getUsersById
// @Description retrieves the users information for a certain id
// @Accept  application/json
// @Param   id              path    int     false        "The row id"
// @Success 200 {array}    Users
// @Resource /api/2.0
// @Router /api/2.0/users/{id} [get]
func GetUser(username string, db *sqlx.DB) (interface{}, error) {
	ret := []Users{}
	arg := Users{}
	arg.Username = username
	queryStr := "select *, concat('" + API_PATH + "users/', username) as self"
	queryStr += ", concat('" + API_PATH + "roles/', role) as roles_name_ref"
	queryStr += " from users WHERE username=:username"
	nstmt, err := db.PrepareNamed(queryStr)
	err = nstmt.Select(&ret, arg)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	nstmt.Close()
	return ret, nil
}

// @Title getUserss
// @Description retrieves the users
// @Accept  application/json
// @Success 200 {array}    Users
// @Resource /api/2.0
// @Router /api/2.0/users [get]
func getUsers(db *sqlx.DB) (interface{}, error) {
	ret := []Users{}
	queryStr := "select *, concat('" + API_PATH + "users/', username) as self"
	queryStr += ", concat('" + API_PATH + "roles/', role) as roles_name_ref"
	queryStr += " from users"
	err := db.Select(&ret, queryStr)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return ret, nil
}

// @Title postUsers
// @Description enter a new users
// @Accept  application/json
// @Param                 Body body     Users   true "Users object that should be added to the table"
// @Success 200 {object}    output_format.ApiWrapper
// @Resource /api/2.0
// @Router /api/2.0/users [post]
func postUser(payload []byte, db *sqlx.DB) (interface{}, error) {
	var v Users
	err := json.Unmarshal(payload, &v)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	sqlString := "INSERT INTO users("
	sqlString += "username"
	sqlString += ",role"
	sqlString += ",email"
	sqlString += ",full_name"
	sqlString += ",ssh_pub_key"
	sqlString += ",local_password"
	sqlString += ",created_at"
	sqlString += ") VALUES ("
	sqlString += ":username"
	sqlString += ",:role"
	sqlString += ",:email"
	sqlString += ",:full_name"
	sqlString += ",:ssh_pub_key"
	sqlString += ",:local_password"
	sqlString += ",:created_at"
	sqlString += ")"
	result, err := db.NamedExec(sqlString, v)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return result, err
}

// @Title putUsers
// @Description modify an existing usersentry
// @Accept  application/json
// @Param   id              path    int     true        "The row id"
// @Param                 Body body     Users   true "Users object that should be added to the table"
// @Success 200 {object}    output_format.ApiWrapper
// @Resource /api/2.0
// @Router /api/2.0/users/{id}  [put]
func putUser(username string, payload []byte, db *sqlx.DB) (interface{}, error) {
	var arg Users
	err := json.Unmarshal(payload, &arg)
	arg.Username = username
	if err != nil {
		log.Println(err)
		return nil, err
	}
	sqlString := "UPDATE users SET "
	sqlString += "username = :username"
	sqlString += ",role = :role"
	sqlString += ",email = :email"
	sqlString += ",full_name = :full_name"
	sqlString += ",ssh_pub_key = :ssh_pub_key"
	sqlString += ",local_password = :local_password"
	sqlString += ",created_at = :created_at"
	sqlString += " WHERE username=:username"
	result, err := db.NamedExec(sqlString, arg)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return result, err
}

// @Title delUsersById
// @Description deletes users information for a certain id
// @Accept  application/json
// @Param   id              path    int     false        "The row id"
// @Success 200 {array}    Users
// @Resource /api/2.0
// @Router /api/2.0/users/{id} [delete]
func delUser(username string, db *sqlx.DB) (interface{}, error) {
	arg := Users{}
	arg.Username = username
	result, err := db.NamedExec("DELETE FROM users WHERE username=:username", arg)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return result, err
}
